/*
 * Copyright 2008 - 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.semagia.atomico.server.storage;

import com.semagia.atomico.MediaType;
import com.semagia.atomico.dm.IWritableRepresentation;
import com.semagia.atomico.server.dm.ICollectionInfo;
import com.semagia.atomico.server.dm.IFragmentInfo;
import com.semagia.atomico.server.dm.ISnapshotInfo;

/**
 * Represents a storage for information about collections, snapshots and 
 * fragments.
 * <p>
 * The main purpose of the storage interface is an abstraction of the backend.
 * The backend may be a file system, a RDBMS, a Topic Maps engine, a RDF graph, 
 * everything which is conformant to this interface.
 * </p>
 * <p>
 * Implementations of this class are meant to be thread-safe.
 * </p>
 * 
 * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
 */
public interface IStorage {

    /**
     * Returns if the storage is modifable.
     *
     * @return <tt>true</tt> if this instance is modifiable, otherwise <tt>false</tt>.
     */
    public boolean isModifiable();

    /**
     * Returns the last modification time.
     * <p>
     * Note: Since this information is often needed this method should be 
     * efficient.
     * </p>
     *
     * @return Last storage modification time.
     * @throws StorageException In case of an error. 
     */
    public long lastModification() throws StorageException;

    /**
     * Returns the last modification time of the specified collection.
     * <p>
     * Note: Since this information is often needed this method should be 
     * efficient.
     * </p>
     *
     * @param collectionId A collection identifier.
     * @return Last collection modification time.
     * @throws StorageException In case of an error.
     */
    public long lastCollectionModification(String collectionId) throws StorageException;

    /**
     * Returns the last fragment modification time of the specified collection.
     * <p>
     * Note: Since this information is often needed this method should be 
     * efficient.
     * </p>
     *
     * @param collectionId A collection identifier.
     * @return Last fragment modification time.
     * @throws StorageException In case of an error. 
     */
    public long lastFragmentModification(String collectionId) throws StorageException;

    /**
     * Returns the last snapshot modification time of the specified collection.
     * <p>
     * Note: Since this information is often needed this method should be 
     * efficient.
     * </p>
     *
     * @param collectionId The collection identifier.
     * @return Last snapshot modification time.
     * @throws StorageException In case of an error.
     */
    public long lastSnapshotModification(String collectionId) throws StorageException;

    /**
     * Returns all available collections.
     *
     * @return Available collections or an empty array if no collections are 
     *          available.
     * @throws StorageException In case of an error.
     */
    public Iterable<? extends ICollectionInfo> getCollectionInfos(SortOrder sortOrder) throws StorageException;

    /**
     * Returns the {@link ICollectionInfo} instance with the specified 
     * <tt>collectionId</tt>.
     *
     * @param collectionId A collection identifier.
     * @return A {@link ICollectionInfo} instance or <tt>null</tt> if the 
     *          collection does not exist.
     * @throws StorageException In case of an error.
     */
    public ICollectionInfo getCollectionInfo(String collectionId) throws StorageException;

    /**
     * Returns the snapshots available for the specified collection 
     * <tt>collectionId</tt>.
     *
     * @param collectionId A collection identifier.
     * @param sortOrder Preferred sort ordering.
     * @return The available snapshots for the specified collection.
     * @throws StorageException In case of an error.
     */
    @Deprecated
    public Iterable<ISnapshotInfo> getSnapshotInfos(String collectionId, SortOrder sortOrder) throws StorageException;

    /**
     * Returns the snapshots available for the specified collection 
     * <tt>collectionId</tt>.
     * <p>
     * The returned iterable must return the snapshots in descending order, the
     * latest snapshot must be listed first.
     * </p>
     *
     * @param collectionId A collection identifier.
     * @return The available snapshots for the specified collection.
     * @throws StorageException In case of an error.
     */
    public Iterable<? extends ISnapshotInfo> getSnapshotInfos(String collectionId) throws StorageException;

    /**
     * Returns the {@link ISnapshotInfo} instance with the specified 
     * <tt>snapshotId</tt>. 
     *
     * @param collectionId A collection identifier.
     * @param snapshotId The snapshot identifier.
     * @return
     * @throws StorageException In case of an error.
     */
    public ISnapshotInfo getSnapshotInfo(String collectionId, String snapshotId) throws StorageException;

    /**
     * Returns a representation of the specified snapshot.
     *
     * @param collectionId A collection identifier.
     * @param snapshotId The snapshot identifier.
     * @param mediaType The media type.
     * @return
     * @throws StorageException In case of an error.
     */
    public IWritableRepresentation getSnapshot(String collectionId, String snapshotId, MediaType mediaType) throws StorageException;

    /**
     * Returns the fragments available for the specified collection.
     *
     * @param collectionId A collection identifier.
     * @return The available fragments for the specified collection.
     * @throws StorageException In case of an error.
     */
    @Deprecated
    public Iterable<IFragmentInfo> getFragmentInfos(String collectionId, SortOrder sortOrder) throws StorageException;

    /**
     * Returns the fragments available for the specified collection.
     * <p>
     * The returned iterable must return the fragments in descending order, the
     * latest fragment must be listed first.
     * </p>
     *
     * @param collectionId A collection identifier.
     * @return The available fragments for the specified collection.
     * @throws StorageException In case of an error.
     */
    public Iterable<? extends IFragmentInfo> getFragmentInfos(String collectionId) throws StorageException;

    /**
     * Returns the {@link IFragmentInfo} instance with the specified 
     * <tt>fragmentId</tt>. 
     *
     * @param collectionId A collection identifier.
     * @param fragmentId The fragment identifier.
     * @return A fragment information or <tt>null</tt> if no fragment with the 
     *          specified <tt>fragmentId</tt> exists within the collection.
     * @throws StorageException In case of an error.
     */
    public IFragmentInfo getFragmentInfo(String collectionId, String fragmentId) throws StorageException;

    /**
     * Returns a representation of the specified fragment.
     *
     * @param collectionId A collection identifier.
     * @param fragmentId The fragment identifier.
     * @param mediaType The media type.
     * @return
     * @throws StorageException In case of an error.
     */
    public IWritableRepresentation getFragment(String collectionId, String fragmentId, MediaType mediaType) throws StorageException;

}
